查看原文
其他

字典禁忌:UPDATE GLOBAL_NAME为空之后的恢复

2016-07-28 熊军 Oracle

(题图授权来自Oracle VP , Sally Piao的摄影佳作)

编辑手记:最近一个朋友遭遇到了这个问题,当GLOBAL_NAME被更新为空值之后,数据库无法启动,我们重温一下老熊的这个测试,记住结论,无论如何不要Update字典表


如果你在数据库的告警日志中发现类似如下的提示,那么多半你的PROPS$发生了更改:

Database Characterset is ZHS16GBK

Updating 7.0.0.0.0 NLS parameters in sys.props$

-- adding 10.2.0.5.0 NLS parameters.


在以前的一篇文章中( 数据库链:Database Link与GLOBAL_NAMES参数的关系 ),我提到千万不能将 Oracle 数据库的 global_name 更新为空。这不,事儿来了。我的一个同事,提到了一个解决办法,不过那个办法实际上是一种不完全恢复的办法,如果没有备份,就行不通。如果没有备份,可以使用BBED来修改块来解决这个问题,不过使用 bbed 仍然比较麻烦。


下面是我一时心血来潮进行的一次测试。测试环境,10.2.0.4 for Linux AS 5.5。注意,不要在生产库上模仿。注意:这个方法可能仅适用于10.2.0.4版本。


首先 UPDATE GLOBAL_NAME 为空,COMMIT 后以 abort 方式关闭数据库,以 abort 方式只是为了增加点难度。之后再启动数据库。




启动失败,不出意料出现 ORA-600[18062] 错误:



下面来解决这个问题。


第1步,重启数据库到 MOUNT 状态:




第2步,在另一个窗口中,使用 gdb




第3步,OPEN 数据库:




约等一会儿,在 alert 日志里面可以看到:




在 gdb 的输出可以看到:




第4步,在 gdb 那里中止 OPEN:




sqlplus 会提示:




这一次,Instance 并没有 terminated。只是 Serverprocess 被 KILL 了。


第5步,还原 GLOBAL_NAME:




虽然可以执行 UPDATE,但是不能 COMMIT。再试试能不能做 DDL:




成功了。


在另会一个会话中查看 GLOBAL_NAME:



GLOBAL_NAME 回来了。


这里通过 DDL 的隐式提交特性来 UPDATE GLOBAL_NAME。其实还有更简单的办法:OCI 主动断开连接时的自动提交。如果 UPDATE 之后,直接退出 sqlplus,UPDATEGLOBAL_NAME 的事务实际也提交了。看起来 ORACLE 这时只是不能执行显式的 COMMIT 语句。


第6步,重启数据库:




看起来只能以 abort 方式关闭数据库:


成功了,数据库起来了。没有数据丢失,没有使用备份。不需要基于时间点的恢复,不需要 BBED,不需要 Resetlog。

如何加入"云和恩墨大讲堂"微信群

搜索 盖国强(Eygle)微信号:eeygle,或者扫描下面二维码,备注:云和恩墨大讲堂,即可入群。每周与千人共享免费技术分享,与讲师在线讨论。


近期文章

七月盛放:云和恩墨大讲堂电子期刊第七期

风云再起:美500强Oracle利润率IT类第一

Oracle 12.2:Sharding 新特性揭秘

用SQL解一道数学题:Gauss和Poincare

Oracle 12c ASM 防火防盗新特性揭秘

DBA入门之路:学习与进阶之经验谈


您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存